package com.program.houai.controller;


import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.program.houai.entity.MemberCardEntity;
import com.program.houai.entity.UserEntity;
import com.program.houai.entity.WxUserEntity;
import com.program.houai.po.WxLoginResponse;
import com.program.houai.po.WxUserDTO;
import com.program.houai.redis.RedisService;
import com.program.houai.service.IUserService;
import com.program.houai.service.IWxUserService;
import com.program.houai.util.*;
import com.program.houai.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 用户接口
 *
 * @author liyinsong
 * @date 2022/1/8 15:27
 */
@Api(tags = "User登录接口")
@RestController
@RequestMapping("/app/login")
@Slf4j
@Validated
public class LoginController {

    @Autowired
    private IUserService userService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IWxUserService wxUserService;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Value("${system.order.secretKey}")
    private String secretKey;


    /**
     * 微信登录
     * @param loginQuery 用户登录凭证
     * @return 登录
     */
    @ApiOperation("微信授权访问")
    @PostMapping(value = "/wx/login", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<Object> wxLogin(@RequestBody @Valid WxLoginVO loginQuery) {
        log.info("UserController#wxLogin, data: {}", loginQuery);

        R<Object> loginResult = userService.wxLogin(loginQuery.getCode());

        //登录失败
        if (!loginResult.isSuccess()) {
            log.error("UserController#wxLogin fail, error msg:{}", loginResult.getMsg());
            return loginResult;
        }
        WxLoginResponse loginResultPO = (WxLoginResponse) loginResult.getData();
        //生成登录状态jwt token
/*        String token = JWTUtils.createJWT(secretKey);

        // TODO 这里应该不是存Redis
        //存入redis设置失效时间，3天
        redisTemplate.opsForValue().set(SystemConstant.LOGIN_TOKEN_KEY + token, loginResult.getData(), SystemConstant.SYSTEM_LOGIN_TIMEOUT, TimeUnit.DAYS);

        //将token，返回前端
        LoginVO wxLoginVO=new LoginVO();
        wxLoginVO.setToken(token);*/
        WxUserDTO wxUserDTO = new WxUserDTO();
        wxUserDTO.setOpenId(loginResultPO.getOpenid());
        userService.registryWxUserInfo(wxUserDTO);
        log.info("UserController#wxLogin success, generated token is [{}]", loginResultPO);
        return R.ok(loginResultPO,"登录成功");
    }


    @ApiOperation("微信登录逻辑")
    @PostMapping(value = "/userLogin", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<String> wxLogin(@RequestBody  UserLoginVO userLoginVO) {

        String  value = (String) redisTemplate.opsForValue().get(SystemConstant.PHONESMSCODE_TOKEN_KEY + userLoginVO.getPhone());
        if (StringUtils.isBlank(value)){
            return R.failed("请输入正确的验证码！！！");
        }
        QueryWrapper<UserEntity> wrap = new QueryWrapper<UserEntity>();
        wrap.eq("phone",userLoginVO.getPhone());
        UserEntity user = userService.getOne(wrap);
        if (user == null ){
            return R.failed("该手机号码未注册！！！");
        }
        //生成登录状态jwt token
        String token = JWTUtils.createJWT(secretKey);

        // TODO 这里应该不是存Redis
        //存入redis设置失效时间，3天
        redisTemplate.opsForValue().set(SystemConstant.LOGIN_TOKEN_KEY + token, user, SystemConstant.SYSTEM_LOGIN_TIMEOUT, TimeUnit.DAYS);

        //清掉验证码缓存
        redisTemplate.delete(SystemConstant.PHONESMSCODE_TOKEN_KEY+ userLoginVO.getPhone());

        log.info("UserController#wxLogin success, generated token is [{}]", token);
        return R.ok(token);
    }

    @ApiOperation("密码登录")
    @PostMapping(value = "/loginByPwd", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<String> loginByPw(@RequestBody  UserLoginVO userLoginVO) {
        QueryWrapper<UserEntity> wrap = new QueryWrapper<UserEntity>();
        wrap.eq("phone",userLoginVO.getPhone());
        UserEntity user = userService.getOne(wrap);
        if (user == null ){
            return R.failed("该手机号码未注册！！！");
        }
        if (!BASE64Utils.decodeBCryptPassword(userLoginVO.getPassword(),user.getPassword())){
            return R.failed("密码不正确！！！");
        }
        //生成登录状态jwt token
        String token = JWTUtils.createJWT(secretKey);

        redisTemplate.opsForValue().set(SystemConstant.LOGIN_TOKEN_KEY + token, user, SystemConstant.SYSTEM_LOGIN_TIMEOUT, TimeUnit.DAYS);

        log.info("UserController#wxLogin success, generated token is [{}]", token);
        return R.ok(token);
    }


    @ApiOperation("修改密码")
    @PostMapping(value = "/updateUserPwd", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<Boolean> updateUserPwd(@RequestBody  UserLoginVO userLoginVO) {
        String  value = (String) redisTemplate.opsForValue().get(SystemConstant.PHONESMSCODE_TOKEN_KEY + userLoginVO.getPhone());
        if (StringUtils.isBlank(value)){
            return R.failed("请输入正确的验证码！！！");
        }
        if (!userLoginVO.getPassword().equals(userLoginVO.getRepPassword())){
            return R.failed("两次输入的密码不一致！！！");
        }
        QueryWrapper<UserEntity> wrap = new QueryWrapper<UserEntity>();
        wrap.eq("phone",userLoginVO.getPhone());
        UserEntity user = userService.getOne(wrap);
        if (user == null ){
            return R.failed("该手机号码未注册！！！");
        }
        String bcryptPassword = BASE64Utils.bcryptPassword(userLoginVO.getPassword());
        user.setPassword(bcryptPassword);
        boolean result = userService.updateById(user);
        //清掉验证码缓存
        redisTemplate.delete(SystemConstant.PHONESMSCODE_TOKEN_KEY+ userLoginVO.getPhone());
        return R.ok(result);
    }


    @ApiOperation("注销登录 3")
    @PostMapping(value = "/logout", produces = MediaType.APPLICATION_JSON_VALUE)
    public R<Object> wxLogout(@RequestHeader String token) {
        Boolean delete = redisTemplate.delete(SystemConstant.LOGIN_TOKEN_KEY + token);
        if (delete) {
            log.info("delete key [{}] success", token);
            return R.ok("注销成功");
        } else {
            log.info("delete key [{}] fail", token);
            return R.failed("注销成功");
        }
    }






}
